import React, { Component } from 'react'
import { connect } from 'react-redux'
import { bindActionCreators } from 'redux'
import { Link } from 'react-router'
import { Table, Spin, Form, Row, Col, Input, Button, Tree, Select, Modal, Dropdown, Menu, Popconfirm, Icon, message, Checkbox } from 'antd'
import _ from 'lodash'
import cn from 'classnames'

import Ajax from 'lib/Ajax'
import { confirmDelete } from 'lib/fun'

const FormItem = Form.Item;
const TreeNode = Tree.TreeNode;

class ModuleName extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      visible: false,
      editType: "",
      rowdata: {},
      data: [],
      autLoading: false,
      authorityList: []
    }
  }

  componentDidMount(){
    this.loadData();
  }

  loadData = ()=>{
    var self = this;

    self.setState({
      loading: true
    });

    Ajax({
      url: '/role/list',
      data: {},
      success: function(data){
        self.setState({
          loading: false,
          data: data
        });
      },
      error: function(error){
        message.error(error);
      }
    });
  }

  loadAuthority = () => {
    var self = this;
    Ajax({
      url: '/authority/list',
      success: function(data){
        const loop = (data) => {
          data.forEach((item) => {
            if(item.children&&item.children.length > 0){
              loop(item.children);
            }else{
              delete item.children
            }
          });
        };
        loop(data);
        self.setState({
          authorityList: data,
          autLoading: false
        });
      },
      error: function(error){
        message.error(error);
      }
    });
  }

  // 操作
  operate = (type, row)=>{
    if(type == 'edit'){
      this.setState({
        visible: true,
        editType: 'edit',
        rowdata: row
      });
    }else{
      this.setState({
        visible: true,
        editType: 'new'
      });
    }
  }

  editOk = (type, rowdata)=>{
    var self = this;
    if(type == 'edit'){
      var area = _.find(this.state.data, function(chr){
        return chr.id == rowdata.id;
      })
      Object.assign(area, rowdata);
      self.setState({
        visible: false,
        rowdata: {},
        data: this.state.data
      });
      message.success('修改记录成功！');
    }else{
      self.setState({
        visible: false,
        rowdata: {}
      });
      message.success('增加记录成功！');
    }
  }
  editCancel = ()=>{
    this.setState({
      visible: false,
      rowdata: {}
    });
  }

  setting = (row)=>{
    var self = this;
    if(this.state.authorityList.length <= 0){
      self.loadAuthority();
      self.setState({
        autLoading: true,
        authorityVisible: true,
        rowdata: row
      });
    }else{
      self.setState({
        authorityVisible: true,
        rowdata: row
      });
    }

  }
  editAutOk = ()=>{
    var self = this;
    self.setState({
      authorityVisible: false,
      rowdata: {}
    });
    message.success('修改权限成功！');
  }
  editAutCancel = ()=>{
    this.setState({
      authorityVisible: false,
      rowdata: {}
    });
  }

  doDelete = (id)=>{
    var self = this;
    confirmDelete(()=>{
      Ajax({
        url: '/role/delete',
        data: {
          "id": id
        },
        success: function(data){
          // this.setState()
          // console.log(data);
          // _.remove(self.state.data, function(d) {
          //   return d.id == id
          // });
          // self.setState({
          //   data: self.state.data
          // });
          self.loadData();
        },
        error: function(error){
          message.error(error);
        }
      });
    }, ()=>{
      message.info('取消删除角色');
    });
  }

  render() {
    const columns = [{
        title: '角色代码',
        dataIndex: 'roleCode'
      }, {
        title: '角色名称',
        dataIndex: 'roleName'
      },{
        title: '操作',
        key: 'action',
        render: (text, record) => (
          <span>
            <Dropdown overlay={
              <Menu>
                <Menu.Item>
                  <a onClick={this.operate.bind(this, "edit", record)} href="javascript:;">编辑</a>
                </Menu.Item>
                <Menu.Item>
                  <a onClick={this.setting.bind(this, record)} href="javascript:;">权限设置</a>
                </Menu.Item>
                <Menu.Item>
                  <a href="javascript:;" onClick={this.doDelete.bind(this, record.id)} >删除</a>
                </Menu.Item>
              </Menu>
            }>
              <a className="ant-dropdown-link" href="javascript:;">
                操作 <Icon type="down" />
              </a>
            </Dropdown>
          </span>
        )
    }];

    return (
      <div className="area">
        <Button type="primary" style={{marginBottom: 15}} icon="plus" onClick={ this.operate.bind(this, 'new') }>新建角色</Button>
        <Table
          columns={ columns }
          dataSource={ this.state.data }
          pagination={ false }
          rowKey="id"
          loading={this.state.loading}
        />
        <EditModule 
          visible={ this.state.visible }
          onOk={ this.editOk }
          onCancel={ this.editCancel }
          type={ this.state.editType }
          rowdata={ this.state.rowdata }
        />
        <AuthorityModule 
          visible={ this.state.authorityVisible }
          onOk={ this.editAutOk }
          onCancel={ this.editAutCancel }
          rowdata={ this.state.rowdata }
          authorityList= { this.state.authorityList }
          autLoading={ this.state.autLoading }
        />
      </div>
    )
  }
}

function mapStateToProps(state) {
  return {}
}

function mapDispatchToProps(dispatch) {
  return bindActionCreators({  }, dispatch)
}

module.exports = connect(mapStateToProps,mapDispatchToProps)(ModuleName)
// 编辑和新建
class Edit extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false
    }
  }

  componentWillReceiveProps(nextProps){
    if(!nextProps.visible){
      this.props.form.resetFields();
    }
  }

  handleCommit = () => {
    var self = this;
    this.props.form.validateFields((err, values) => {
      if(this.state.loading){
        return
      }
      self.setState({
        loading: true
      });
      const { type, rowdata } = this.props;
      if(self.props.type == 'edit'){
        values.id = rowdata.id
      }
      Ajax({
        url: '/role/save',
        data: values,
        success: function(data){
          self.setState({
            loading: false
          });
          self.props.onOk(self.props.type, data);
        },
        error: function(error){
          this.setState({
            loading: false
          });
          message.error(error);
        }
      });
    });
  }

  onCancel = ()=>{
    this.setState({
      loading: false
    });
    this.props.onCancel();
  }


  render() {
    const { getFieldDecorator } = this.props.form;
    const formItemLayout = {
      labelCol: { span: 10 },
      wrapperCol: { span: 14 },
    };
    const { visible, type, rowdata } = this.props;
    return (<Modal 
              title={ type == 'edit'?"编辑角色信息":"新建角色信息" } 
              visible={visible}
              onOk={ this.handleCommit } 
              onCancel={ this.onCancel }
              okText="确定" 
              cancelText="取消"
            >
              <Spin spinning={this.state.loading}>
                <Form
                  horizontal
                >
                  <Row gutter={20}>
                    <Col span={12}>
                      <FormItem {...formItemLayout} label="角色代码">
                        {getFieldDecorator("roleCode",{
                          initialValue: type == 'edit'?rowdata.roleCode:"",
                          rules: [{
                            required: true, message: '请输入角色代码',
                          }]
                        })(
                          type == 'edit'?<Input disabled/>:<Input />
                        )}
                      </FormItem>
                    </Col>
                    <Col span={12}>
                      <FormItem {...formItemLayout} label="角色名称">
                        {getFieldDecorator("roleName",{
                          initialValue: type == 'edit'?rowdata.roleName:"",
                          rules: [{
                            required: true, message: '请输入角色名称',
                          }]
                        })(
                          <Input />
                        )}
                      </FormItem>
                    </Col>
                  </Row>
                  <Row gutter={20} className="area-modifier">
                    <Col span={24}>
                      <FormItem labelCol={{ span: 5 }} wrapperCol={{ span: 19 }} label="备注">
                        {getFieldDecorator("remark",{
                          initialValue: type == 'edit'?rowdata.remark:"",
                        })(
                          <Input type="textarea"/>
                        )}
                      </FormItem>
                    </Col>
                  </Row>
                </Form>
              </Spin>
            </Modal>);
  }
}
var EditModule = Form.create()(Edit);


class Authority extends Component {
  constructor(props) {
    super(props);
    this.state = {
      loading: false,
      closeKeys: [],
      selectedKeys: []
    }
  }

  // componentDidMount(){
  //   this.getAuthority();
  // }

  componentWillReceiveProps(nextProps){
    if(!nextProps.visible){
      this.setState({
        closeKeys: [],
        selectedKeys: []
      });
    }else if(nextProps.rowdata.id&&nextProps.rowdata.id != this.props.rowdata.id){
      this.getAuthority(nextProps.rowdata.id);
    }
  }

  handleCommit = () => {
    var self = this;
    if(this.state.loading){
      return
    }
    self.setState({
      loading: true
    });
    const { type, rowdata } = this.props;
    Ajax({
      url: '/authority/saveByRoleId',
      data: {
        roleId: rowdata.id,
        authIds: this.state.selectedKeys,
      },
      success: function(data){
        self.setState({
          loading: false
        });
        self.props.onOk();
      },
      error: function(error){
        this.setState({
          loading: false
        });
        message.error(error);
      }
    });
  }

  getAuthority = (id)=>{
    var self = this;
    self.setState({
      loading: false
    });
    Ajax({
      url: '/authority/getByRoleId',
      data: {
        id: id
      },
      success: function(data){
        console.log(data);
        var selectedKeys = [];
        const loop = (data) => {
          data.forEach((item) => {
            selectedKeys.push(item.id);
            if(item.children&&item.children.length > 0){
              loop(item.children);
            }
          });
        };
        loop(data);
        self.setState({
          loading: false,
          selectedKeys: selectedKeys
        });
      },
      error: function(error){
        self.setState({
          loading: false
        });
        message.error(error);
      }
    });
  }

  onCancel = ()=>{
    this.setState({
      loading: false
    });
    this.props.onCancel();
  }

  findParent = (id)=>{
    var parent = [];
    const loop = (data) => {
      var isParent = false;
      data.forEach((item) => {
        if(item.id == id){
          isParent = true
        }else if(item.children){
          isParent = loop(item.children);
          isParent&&(parent.push(item.id))
        }
      });
      return isParent
    };
    loop(this.props.authorityList);
    return parent
  }

  checkboxCanCancel = (id)=>{
    var canCancel = true;
    const loop = (data, find) => {
      data.forEach((item) => {
        if(find){
          if(_.find(this.state.selectedKeys, function(n){return item.id == n})){
            canCancel = false
          }else if(item.children){
            loop(item.children, true)
          }
        }else{
          if(item.id == id){
            item.children&&(loop(item.children, true))
          }else if(item.children){
            loop(item.children, false)
          }
        }
      });
    };
    loop(this.props.authorityList, false);
    return canCancel
  }

  onChange = (e)=>{
    // console.log(e.target.checked, e.target)
    var id = e.target.value;
    var find = _.find(this.state.selectedKeys, function(n){
      return id == n
    });
    if(e.target.checked){
      if(!find){
        this.setState({
          selectedKeys: _(this.state.selectedKeys).concat(id, this.findParent(id)).value()
        });
      }
    }else{
      if(find&&this.checkboxCanCancel(id)){
        _.remove(this.state.selectedKeys, function(n) {return id == n});
        this.setState({
          selectedKeys: this.state.selectedKeys
        });
      }else{
        this.setState({
          selectedKeys: this.state.selectedKeys
        });
      }
    }
  }

  toggleTree = (id)=>{
    var find = _.find(this.state.closeKeys, function(n){
      return id == n
    });
    if(find){
      _.remove(this.state.closeKeys, function(n) {return id == n});
      this.setState({
        closeKeys: this.state.closeKeys
      });
    }else{
      this.setState({
        closeKeys: _(this.state.closeKeys).concat(id).value()
      });
    }
  }

  isClose = (id)=>{
    return _.find(this.state.closeKeys, function(colse){ return colse == id })
  }

  isSelected = (id)=>{
    return !!_.find(this.state.selectedKeys, function(select){ return select == id })
  }

  render() {
    console.log(this.state.selectedKeys);
    const formItemLayout = {
      labelCol: { span: 10 },
      wrapperCol: { span: 14 },
    };
    const { visible, rowdata, authorityList, autLoading,  } = this.props;
    const expandedKeys = [];
    const loop = data => data.map((item) => {
      // expandedKeys.push(item.id+"");
      if (item.children&&item.children.length > 0) {
        return (<li key={item.id}>
                <span className={cn("ant-tree-switcher", {"ant-tree-noline_open": !this.isClose(item.id),"ant-tree-noline_close": this.isClose(item.id)})} onClick={ this.toggleTree.bind(this, item.id) }></span>
                <Checkbox checked={this.isSelected(item.id)} onChange={this.onChange} value={ item.id }/>
                <a title={item.name} className="ant-tree-node-content-wrapper" href="javascript:;">
                  <span className="ant-tree-title">{item.name}</span>
                </a>
                {
                  !this.isClose(item.id)&&(<ul className="ant-tree-child-tree ant-tree-child-tree-open">
                    { loop(item.children) }
                  </ul>)
                }
              </li>)
      }
      return (<li key={item.id}>
                <span className="ant-tree-switcher ant-tree-switcher-noop ant-tree-noline_docu"></span>
                <Checkbox checked={this.isSelected(item.id)} onChange={this.onChange} value={ item.id }/>
                <a title={item.name} className="ant-tree-node-content-wrapper" href="javascript:;">
                  <span className="ant-tree-title">{item.name}</span>
                </a>
              </li>)
    });
    const treeNodes = loop(authorityList);
    
    return (<Modal 
              title={`编辑${rowdata.roleName||""}权限`}
              visible={visible}
              onOk={ this.handleCommit } 
              onCancel={ this.onCancel }
              okText="确定" 
              cancelText="取消"
            >
              <Spin spinning={this.state.loading||autLoading}>
                <div style={{minHeight: 150}}>
                  <div className="ant-tree">
                    { treeNodes }
                  </div>
                </div>
              </Spin>
            </Modal>);
  }
}
var AuthorityModule = Authority